import * as THREE from "three";

import { CONFIG } from "../../app/config.js";
import { OBJECTS, PLAYERS, UTILS } from "../declarations.js";
import { TOOLS } from "../tools/tools.js";
import TweenMax from "gsap/TweenMaxBase";

let lights, models, materials, textures, actors, players, groups;

let ACTOR = {
  init: () => {
    models = OBJECTS.models;
    materials = OBJECTS.materials;
    textures = OBJECTS.textures;
    actors = OBJECTS.actors;
    lights = OBJECTS.lights;
    groups = OBJECTS.groups;
    // me = PLAYERS.me
    players = PLAYERS.others;

    let geo = new THREE.ConeGeometry(0.5, 1, 4);
    let arrow_mesh = new THREE.Mesh(geo, materials.arrow);
    arrow_mesh.scale.z = 0.5;

    // actors.arrow = new THREE.Object3D().add(arrow_mesh)

    // 下方为初始化轮胎
    actors.arrow = models.tire;
    actors.arrow.children[0].material = materials.arrow;
    actors.arrow.children[0].material.depthTest = false;
    actors.arrow.children[0].renderOrder = 1;
    actors.arrow.scale.set(3,2,2); // 这里我把原轮胎加大了，这样绘图的时候看的更清晰
    // actors.arrow.translateZ(0.5)


    // Change tire material settings
    actors.arrow.traverse((e)=>{
      console.log(e.type)
      if(e.type == "Mesh"){
        e.material.envMap = textures.bg // add environment map for reflection and passive lighting for all materials
        if(e.material.name == "Yellow"){
          e.material.emissiveIntensity = 1 // fix intensity problem from blender, re-set it
          e.material.emissive = new THREE.Color("#FFA500") // fix color management issue with blender material export
        }
      }
    })

    geo = new THREE.IcosahedronGeometry(1, 1);
    let mesh = new THREE.Mesh(geo, materials.arrow_block);

    // actors.arrow.add(mesh);

    // actors.arrow.rotation.x = TOOLS.d2r(180)
    // actors.arrow.rotation.y = TOOLS.d2r(180)

    actors.low = new THREE.Object3D();
    actors.mid = new THREE.Object3D();
    actors.low.add(actors.arrow);
    actors.mid.add(actors.low);
    actors.pointer = new THREE.Object3D();
    actors.pointer.add(actors.mid);

    actors.dummy = new THREE.Mesh(new THREE.IcosahedronGeometry(0.025, 1));
    actors.dummy.material = materials.dots;

    ///////////////////////////////////////////////////////////////////////////////////
    //
    //  Make a camera container, this will be sharing the same basic transform values
    //  as pointer (pointer)
    //
    ///////////////////////////////////////////////////////////////////////////////////

    // let cam_container = new THREE.Object3D()
    let cam_container = new THREE.Mesh(
      new THREE.BoxGeometry(2, 2, 2),
      new THREE.MeshBasicMaterial({
        color: 0xff0000,
        wireframe: true,
        side: THREE.DoubleSide,
      })
    );

    cam_container = new THREE.Object3D();

    actors.cam_container = cam_container;

    ///////////////////////////////////////////////////////////////////////////////////

    let cam_pointer = new THREE.PerspectiveCamera(
      75,
      UTILS.sw / UTILS.sh,
      0.1,
      1000
    );

    OBJECTS.cameras.push(cam_pointer);

    // cam_pointer.position.x = 1
    cam_pointer.position.z = 2;
    cam_pointer.position.y = 2;

    cam_pointer.translateZ(10);

    let cam_pointer_helper = new THREE.CameraHelper(cam_pointer);

    actors.cam_pointer = cam_pointer;
    actors.cam_pointer_helper = cam_pointer_helper;
    actors.cam_container.add(actors.cam_pointer);

    OBJECTS.cam_target = new THREE.Vector3();

    ///////////////////////////////////////////////////////////////////////////////////
    //
    //  Make spawn points for additional lines
    //
    ///////////////////////////////////////////////////////////////////////////////////

    // prepare the container & attach it inside the arrow
    // object since it will be rotated via deviceorientation

    actors.spawn_point_container = new THREE.Object3D();
    actors.arrow.add(actors.spawn_point_container);

    let spawn_point_ref = new THREE.Mesh(
      new THREE.IcosahedronGeometry(0.1, 1),
      materials.dots
    );

    let sp1 = spawn_point_ref.clone();
    let sp2 = spawn_point_ref.clone();
    let sp3 = spawn_point_ref.clone();

    sp1.name = "sp1";
    sp2.name = "sp2";
    sp3.name = "sp3";

    OBJECTS.sps = [];

    OBJECTS.sps.push(sp1, sp2, sp3);

    const dist = 1.5;

    sp1.position.set(0, 0, dist);
    sp2.position.set(dist, 0, -dist);
    sp3.position.set(-dist, 0, -dist);

    sp1.visible = sp2.visible = sp3.visible = false;

    actors.spawn_point_container.add(sp1, sp2, sp3);
    TweenMax.to(actors.spawn_point_container.rotation, 5, {
      ease: Linear.easeNone,
      y: TOOLS.d2r(360),
      loop: true,
      repeat: -1,
    });

    ///////////////////////////////////////////////////////////////////////////////////
    //
    //  Add lights in arrow
    //
    ///////////////////////////////////////////////////////////////////////////////////

    let ptlight = new THREE.PointLight(new THREE.Color(1, 1, 1), 2, 20);
    ptlight.castShadow = true;
    let ptlight2 = ptlight.clone();
    ptlight.position.set(-3, 0, 3);
    ptlight2.position.set(3, 0, -3);

    let axis = new THREE.PointLightHelper(ptlight, 0.1);

    actors.ptlightaxishelper = axis;

    ///////////////////////////////////////////////////////////////////////////////////
    //
    //  Prep the car
    //
    ///////////////////////////////////////////////////////////////////////////////////

    actors.car_container = new THREE.Object3D();
    geo = new THREE.BoxGeometry(5, 5, 10);
    mesh = new THREE.Mesh(geo, materials.normal);

    mesh.castShadow = true;

    models.car.children[0].traverse((e) => {
      if (e.type == "Mesh") {
        e.material.envMap = textures.bg
      }
    })

    actors.car_container.add(models.car.children[0]);
    // actors.car_container.add(mesh);

    actors.car = actors.car_container.children[0].children[1];

    // using camera attached inside the car 3d model (glb)

    // using custom setup for the chase cam / rear cam
    actors.cam_rear = new THREE.Object3D();

    let camera = new THREE.PerspectiveCamera(
      CONFIG.camera.world.viewAngle,
      UTILS.sw / UTILS.sh,
      CONFIG.camera.world.near,
      CONFIG.camera.world.far
    );
    // camera.translateZ(1.5)
    camera.translateX(.8);
    camera.rotation.z = Math.PI * -22.5
    // camera.rotation.y = Math.PI * 90
    actors.cam_rear.add(camera);
    OBJECTS.cameras.push(camera);

    let m_test = new THREE.Mesh(
      new THREE.BoxGeometry(8, 8, 8),
      materials.normal
    );
    m_test.castShadow = true;

    actors.car.traverse((e) => {
      if (e.type == "Mesh") e.material.envMap = textures.bg;
    });

    /*
    //把相机挂到车上 
    actors.car.add(camera);
    camera.rotation.z = 0;
    camera.position.set(0,3,4);  
    */

    const carscale = 0.15;

    actors.car_container.scale.set(carscale, carscale, carscale);
    actors.car_container.children[0].rotation.z = TOOLS.d2r(-90);
    actors.car_container.visible = false;

    actors.car_container.traverse((e) => {
      // console.log(e);
      if (e.type == "Mesh") {
        e.material.depthTest = true;
        e.renderOrder = 2;
        e.castShadow = true;
      }
    });

  },
};

export { ACTOR };
